#include <netcdf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void handle_netcdf_error(int ierr, const char *file, int line) {
  if (ierr != NC_NOERR) {
    printf("[Error]: %s:%d: %s\n", file, line, nc_strerror(ierr));
  }
}

void write_string(int ncid, int varid, int i, const char *str) {
  int ierr;
  char *tmp[1];
  tmp[0] = malloc(sizeof(char)*(strlen(str)+1));
  strncpy(tmp[0], str, strlen(str));
  size_t idx[1];
  idx[0] = i;
  ierr = nc_put_var1_string(ncid, varid, idx, (const char **)tmp);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  free(tmp[0]);
}

void add_string_vars(
  const char *file_path,
  const char *time_reference,
  const char *sweep_mode,
  const char *follow_mode,
  const char *prt_mode) {
  int ncid, ierr;
  ierr = nc_open(file_path, NC_WRITE|NC_NETCDF4, &ncid);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  // Get sweep group size.
  int nsweep;
  ierr = nc_inq_grps(ncid, &nsweep, NULL);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  // Get sweep dimension.
  int sweep_dimid;
  ierr = nc_inq_dimid(ncid, "sweep", &sweep_dimid);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  // Add sweep_group_name variable.
  ierr = nc_redef(ncid);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  int dimids[1], sweep_group_name_varid;
  dimids[0] = sweep_dimid;
  ierr = nc_def_var(ncid, "sweep_group_name", NC_STRING, 1, dimids, &sweep_group_name_varid);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  ierr = nc_enddef(ncid);
  handle_netcdf_error(ierr, __FILE__, __LINE__);
  for (int i = 0; i < nsweep; i++) {
    char grpname[10];
    sprintf(grpname, "sweep_%2.2d", i + 1);
    write_string(ncid, sweep_group_name_varid, i, grpname);
  }
  // Add time_reference, sweep_mode, follow_mode, prt_mode in each group.
  for (int i = 0; i < nsweep; i++) {
    ierr = nc_redef(ncid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    char grpname[10];
    sprintf(grpname, "sweep_%2.2d", i + 1);
    int sweep_grpid;
    ierr = nc_inq_grp_ncid(ncid, grpname, &sweep_grpid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    int time_reference_varid;
    ierr = nc_def_var(sweep_grpid, "time_reference", NC_STRING, 0, NULL, &time_reference_varid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    int sweep_mode_varid;
    ierr = nc_def_var(sweep_grpid, "sweep_mode", NC_STRING, 0, NULL, &sweep_mode_varid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    int follow_mode_varid;
    ierr = nc_def_var(sweep_grpid, "follow_mode", NC_STRING, 0, NULL, &follow_mode_varid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    int prt_mode_varid;
    ierr = nc_def_var(sweep_grpid, "prt_mode", NC_STRING, 0, NULL, &prt_mode_varid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    ierr = nc_enddef(ncid);
    handle_netcdf_error(ierr, __FILE__, __LINE__);
    write_string(sweep_grpid, time_reference_varid, 0, time_reference);
    write_string(sweep_grpid, sweep_mode_varid, 0, sweep_mode);
    write_string(sweep_grpid, follow_mode_varid, 0, follow_mode);
    write_string(sweep_grpid, prt_mode_varid, 0, prt_mode);
  }
}
